
#include <gtk/gtk.h>
#include "support.h"
#include "window.h"
#include "codeview.h"
#include "keypad.h"
#include "fileops.h"
#include "statusbar.h"
#include "page_state.h"
#include "dialog.h"
#include "widget.h"

/*################### Globals #######################*/
GtkWidget *codeview_notebook ;
GtkWidget *last_page_label;
GtkWidget *current_page;
GtkWidget *current_code_tree;
GtkTreeModel *current_code_model;
GtkTreeSelection *current_code_selection;
GtkTreeIter current_code_iter;


/*################### Static functions ################*/
static void gsim_page_switched(GtkNotebook *notebook,GtkNotebookPage *page,guint page_num,gpointer data);
static void codeview_address_edited(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data);
static void codeview_comment_edited(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data);
static void codeview_label_edited(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data);
static gboolean codeview_pop_menu(GtkWidget *widget, GdkEvent *event);
static void codeview_enter_label(GtkWidget *widget, gpointer data);
static void codeview_op1_edited(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data);
static void gsim_toggle_breakpoint(void);

/*################## Get the lable of a new page #####################*/
gchar *codeview_new_label(void)
{
	static gchar new_label[15];
	static gint _new=1;
	g_snprintf(new_label,14,"Untitled%d",_new);
	_new++;
	return new_label;
}

/*################## Page switched handler #####################*/
static void gsim_page_switched(GtkNotebook *notebook,GtkNotebookPage *page,guint page_num,gpointer data)
{
	GtkWidget *curr_page;
	GList *tree;
	
	/*save prev data*/
	set_state_data(last_page_label);
	
	curr_page=gtk_notebook_get_nth_page(notebook,page_num);
	/*if page is one hendler is called twice*/
	if(gtk_notebook_get_n_pages(GTK_NOTEBOOK(codeview_notebook))==1)
	{
		last_page_label=gtk_notebook_get_tab_label(notebook,curr_page);
	}
	else 
	{          /*set prevoius page insenstive*/
		if(last_page_label)
			gtk_widget_set_sensitive(last_page_label,FALSE);
		last_page_label=gtk_notebook_get_tab_label(notebook,curr_page);
		gtk_widget_set_sensitive(last_page_label,TRUE);
	}
	
	/*set the current codetree and corrsponding model */
	current_page=curr_page;
	tree=gtk_container_get_children(GTK_CONTAINER(curr_page));
	current_code_tree=tree->data;
	current_code_model=gtk_tree_view_get_model(GTK_TREE_VIEW(current_code_tree));
	current_code_selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(current_code_tree));
	g_list_free(tree);
	
	/*initilise and save state of the page*/
	get_state_data(last_page_label);
	gsim_keypad_set_state();
	
	/*append the iter to last row*/
	gint prev_row=gtk_tree_model_iter_n_children(current_code_model,NULL)-1;
	if(prev_row>=0)
		gtk_tree_model_iter_nth_child(current_code_model,&current_code_iter,NULL,prev_row);
	
	/*update the statusbar*/
	if(edit_state)
		gsim_update_statusbar(EDIT_SBAR,_("On"));
	else
		gsim_update_statusbar(EDIT_SBAR,_("Off"));
	gsim_update_statusbar(FILE_SBAR,filename);
	
	return;
}	

/*################# Callback when address is edited #################*/
static void codeview_address_edited(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data)
{
	GtkTreeIter insertion_iter;
	GtkTreePath *insertion_path;
	gint i,m;
	gchar *final_value;
	gchar *ans;
	
	insertion_path = gtk_tree_path_new_from_string (path_string);
	gtk_tree_model_get_iter (GTK_TREE_MODEL(current_code_model), &insertion_iter,insertion_path);
	final_value=g_utf8_strup(new_text,4);
	
	if(*final_value=='\0')
	{
		gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&insertion_iter,ADDR_COL,final_value,-1);
		g_free(final_value);
		return;
	}
	
	ans=g_malloc(5);
	*ans='\0';
	m=4-g_utf8_strlen(final_value,-1);
	for(i=0;i<m;i++)
		g_strlcat(ans,"0",5);
	
	for(i=0;i<g_utf8_strlen(final_value,-1);i++)
	{
		if(g_unichar_isxdigit(*(final_value+i)))
			continue;
		else 
		{
			g_free(final_value);
			g_free(ans);
			return;
		}
	}
	
	g_strlcat(ans,final_value,5);
	
	gchar *address;
	gtk_tree_model_get(current_code_model, &insertion_iter,ADDR_COL,&address,-1);
	if(g_ascii_strcasecmp(ans,address))
	{
		gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&insertion_iter,ADDR_COL,ans,-1);
		save_state=1;
	}
	g_free(final_value);
	g_free(ans);
	g_free(address);
	gsim_update_statusbar(FILE_SBAR,filename);
}

/*################### comment column callback ##################*/
static void codeview_comment_edited(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data)
{
	GtkTreeIter new_iter;
	GtkTreePath *new_path = gtk_tree_path_new_from_string (path_string);
	gtk_tree_model_get_iter (current_code_model, &new_iter,new_path);
	gchar *comment;
	gtk_tree_model_get(current_code_model, &new_iter,COMMT_COL,&comment,-1);
	if(g_ascii_strcasecmp(new_text,comment))
	{
		gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&new_iter,COMMT_COL,new_text,-1);
		save_state=1;
	}
	g_free(comment);
	gsim_update_statusbar(FILE_SBAR,filename);
}

/*################ label column callback #####################*/
static void codeview_label_edited(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data)
{
	/*cheak for invalid label*/
	if(g_ascii_isdigit(*new_text))
	{
		gsim_message(_("The lable must start with a alphabet\n or a underscore or a doller sign ."),GTK_MESSAGE_ERROR);
		return;
	}
	
	gint i;
	for(i=0;i<g_utf8_strlen(new_text,7);i++)
	{
		if(!g_ascii_isalpha(*(new_text+i))&&*(new_text+i)!='_'&&*(new_text+i)!='$'
										&&!(*(new_text+i)==':'&&(i==g_utf8_strlen(new_text,7)-1)))
		{
			gsim_message(_("The label is invalid. Valid characters\n are [ a-z ] , [ A-Z ] , _ , $ ."),GTK_MESSAGE_ERROR);
			return;
		}
	}
	
	GtkTreeIter new_iter;
	gchar *ans;
	gchar *value=g_malloc(8);
	GtkTreePath *new_path = gtk_tree_path_new_from_string (path_string);
	gtk_tree_model_get_iter (current_code_model, &new_iter,new_path);
	*value='\0';
	g_strlcat(value,new_text,7);
	int len;
	if((len=g_utf8_strlen(value,-1))!=0)
	{
	if(*(value+len-1)!=':')
	     g_strlcat(value,":",8);
	}
	
	ans=g_utf8_strup(value,-1);
	
	gchar *label;
	gtk_tree_model_get(current_code_model, &new_iter,LABEL_COL,&label,-1);
	if(g_ascii_strcasecmp(ans,label))
	{
		gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&new_iter,LABEL_COL,ans,-1);
		save_state=1;
	}
	g_free(value);
	g_free(ans);
	g_free(label);
	gsim_update_statusbar(FILE_SBAR,filename);
}

/*################# Op1 column edited ####################*/
static void codeview_op1_edited(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data)
{
	/*if user clicked at wrong cell*/
	GtkTreeIter iter;
	gchar *mnemonic;
	gtk_tree_selection_get_selected(current_code_selection,&current_code_model, &iter);
	gtk_tree_model_get(current_code_model, &iter,MNE_COL,&mnemonic,-1);
	if((g_strcasecmp(mnemonic,"JMP")&&g_strcasecmp(mnemonic,"CALL")&&g_strcasecmp(mnemonic,"JZ")&&g_strcasecmp(mnemonic,"JNZ")&&
			g_strcasecmp(mnemonic,"JC")&&g_strcasecmp(mnemonic,"JNC")&&g_strcasecmp(mnemonic,"JPE")&&g_strcasecmp(mnemonic,"JPO")&&
			g_strcasecmp(mnemonic,"JM")&&g_strcasecmp(mnemonic,"JP")&&g_strcasecmp(mnemonic,"CZ")&&g_strcasecmp(mnemonic,"CNZ")&&
			g_strcasecmp(mnemonic,"CC")&&g_strcasecmp(mnemonic,"CNC")&&g_strcasecmp(mnemonic,"CPE")&&g_strcasecmp(mnemonic,"CPO")&&
			g_strcasecmp(mnemonic,"CM")&&g_strcasecmp(mnemonic,"CP"))|| !mnemonic)
	{
		g_object_set(cell,"editable",FALSE,NULL);
		g_free(mnemonic);
		return;
	}
	
	/*cheak for invalid label*/
	if(g_ascii_isdigit(*new_text))
	{
		gsim_message(_("The lable must start with a alphabet\n or a underscore or a doller sign ."),GTK_MESSAGE_ERROR);
		g_object_set(cell,"editable",FALSE,NULL);
		g_free(mnemonic);
		return;
	}
	
	gint i;
	for(i=0;i<g_utf8_strlen(new_text,7);i++)
	{
		if(!g_ascii_isalpha(*(new_text+i))&&!g_ascii_isdigit(*(new_text+i))&&*(new_text+i)!='_'&&*(new_text+i)!='$')
		{
			gsim_message(_("The label is invalid. Valid characters\n are [ a-z ] , [ A-Z ] , _ , $ ."),GTK_MESSAGE_ERROR);
			g_object_set(cell,"editable",FALSE,NULL);
			g_free(mnemonic);
			return;
		}
	}
	
	/*test if an empty label is provided*/
	if(*new_text=='\0')
	{
		gsim_message(_("Please provide a label."),GTK_MESSAGE_ERROR);
		g_object_set(cell,"editable",FALSE,NULL);
		g_free(mnemonic);
		return;
	}
	
	/*Enter the label*/
	GtkTreeIter new_iter;
	gchar *ans;
	GtkTreePath *new_path = gtk_tree_path_new_from_string (path_string);
	gtk_tree_model_get_iter (current_code_model, &new_iter,new_path);
	ans=g_utf8_strup(new_text,7);
	
	gchar *op1;
	gtk_tree_model_get(current_code_model, &new_iter,OP1_COL,&op1,-1);
	if(g_ascii_strcasecmp(ans,op1))
	{
		gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&new_iter,OP1_COL,ans,-1);
		save_state=1;
	}
	g_free(ans);
	g_object_set(cell,"editable",FALSE,NULL);
	g_free(mnemonic);
	g_free(op1);
	gsim_update_statusbar(FILE_SBAR,filename);
	return;
}

/*#################### Pop up menu when right clicked ####################*/
static gboolean codeview_pop_menu(GtkWidget *widget, GdkEvent *event)
{
  	GtkMenu *menu=GTK_MENU(widget);
	GdkEventButton *event_button;
	GtkTreeIter iter;

  	if (event->type != GDK_BUTTON_PRESS) /*not a button press event*/
  		return FALSE;
	
    event_button = (GdkEventButton *) event;
    if (event_button->button != 3)      /*button is not right*/
		return FALSE;
		
	gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 
	 			event_button->button, event_button->time);
	/*Activate or deactivate the menuitems*/
	GList *menuitems;
	menuitems=gtk_container_get_children(GTK_CONTAINER(menu));
	
	if(gtk_tree_selection_get_selected(current_code_selection,&current_code_model, &iter)==FALSE)
	{
		gint n_items;
		for(n_items=0;n_items<8;n_items++)
			gtk_widget_set_sensitive(GTK_WIDGET(g_list_nth_data(menuitems,n_items)),FALSE);
	}
	else
	{
		/*enter label*/
		gchar *mnemonic;
		gtk_tree_model_get(current_code_model, &iter,MNE_COL,&mnemonic,-1);
		if(!mnemonic||(g_strcasecmp(mnemonic,"JMP")&&g_strcasecmp(mnemonic,"CALL")&&g_strcasecmp(mnemonic,"JZ")&&g_strcasecmp(mnemonic,"JNZ")&&
			g_strcasecmp(mnemonic,"JC")&&g_strcasecmp(mnemonic,"JNC")&&g_strcasecmp(mnemonic,"JPE")&&g_strcasecmp(mnemonic,"JPO")&&
			g_strcasecmp(mnemonic,"JM")&&g_strcasecmp(mnemonic,"JP")&&g_strcasecmp(mnemonic,"CZ")&&g_strcasecmp(mnemonic,"CNZ")&&
			g_strcasecmp(mnemonic,"CC")&&g_strcasecmp(mnemonic,"CNC")&&g_strcasecmp(mnemonic,"CPE")&&g_strcasecmp(mnemonic,"CPO")&&
			g_strcasecmp(mnemonic,"CM")&&g_strcasecmp(mnemonic,"CP")))
		{
			gtk_widget_set_sensitive(GTK_WIDGET(g_list_nth_data(menuitems,0)),FALSE);
		}
		else
		{
			gtk_widget_set_sensitive(GTK_WIDGET(g_list_nth_data(menuitems,0)),TRUE);
		}
		g_free(mnemonic); /*free the string we get*/
		
		/*Set other menuitems sensitive*/
		gint n_items;
		for(n_items=1;n_items<8;n_items++)
			gtk_widget_set_sensitive(GTK_WIDGET(g_list_nth_data(menuitems,n_items)),TRUE);
	}
		
	g_list_free(menuitems);
  	return TRUE;
}

/*############# Enter a label after an jmp or call #################*/
static void codeview_enter_label(GtkWidget *widget, gpointer data)
{
	GtkTreeViewColumn *column;
	GtkCellRendererText *cell;
	GList *cell_list;
	column=gtk_tree_view_get_column(GTK_TREE_VIEW(current_code_tree),3);
	cell_list=gtk_tree_view_column_get_cell_renderers(column);
	cell=GTK_CELL_RENDERER_TEXT(cell_list->data);
	g_object_set(cell,"editable",TRUE,NULL);
	gtk_tree_view_column_focus_cell(column,GTK_CELL_RENDERER(cell));
	g_list_free(cell_list);
}

/*############## insert a row after a selected row ###############*/
void gsim_insert_row_after()
{
	GtkTreeIter selected_iter;
	gtk_tree_selection_get_selected(current_code_selection,&current_code_model, &selected_iter);
	gtk_tree_store_insert_after(GTK_TREE_STORE(current_code_model),&current_code_iter,NULL,&selected_iter);
	gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&current_code_iter,ADDR_COL,"",LABEL_COL,"",OP1_COL,"",OP2_COL,"",COMMT_COL,"",-1);
	save_state=1;
	gsim_update_statusbar(FILE_SBAR,filename);
}

/*############### insert a row before a selected row ###############*/
void gsim_insert_row_before()
{
	GtkTreeIter selected_iter;
	gtk_tree_selection_get_selected(current_code_selection,&current_code_model, &selected_iter);
	gtk_tree_store_insert_before(GTK_TREE_STORE(current_code_model),&current_code_iter,NULL,&selected_iter);
	gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&current_code_iter,ADDR_COL,"",LABEL_COL,"",OP1_COL,"",OP2_COL,"",COMMT_COL,"",-1);
	save_state=1;
	gsim_update_statusbar(FILE_SBAR,filename);
}

/*############### remove the selected row ######################*/
void gsim_remove_row()
{
	GtkTreeIter selected_iter;
	gtk_tree_selection_get_selected(current_code_selection,&current_code_model, &selected_iter);
	gtk_tree_store_remove(GTK_TREE_STORE(current_code_model),&selected_iter);
	save_state=1;
	gsim_update_statusbar(FILE_SBAR,filename);
}

/*################# Toggle a breakpoint ####################*/
static void gsim_toggle_breakpoint(void)
{
	GtkTreeIter selected_iter;
	GdkPixbuf *br;
	gtk_tree_selection_get_selected(current_code_selection,&current_code_model, &selected_iter);
	gtk_tree_model_get(current_code_model,&selected_iter,BR_COL,&br,-1);
	if(br)
		gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&selected_iter,BR_COL,NULL,-1);
	else
		gtk_tree_store_set(GTK_TREE_STORE(current_code_model),&selected_iter,BR_COL,code_brpoint_pixmap,-1);
}

/*##################### Toggle the row editing ##################*/
void gsim_edit(void)
{
	if(edit_state)
	{
		edit_state=0;
		gsim_update_statusbar(EDIT_SBAR,_("Off"));
	}
	else
	{
		edit_state=1;
		gsim_update_statusbar(EDIT_SBAR,_("On"));
	}
}
/*fix for window display code*/
void gsim_button_fix_win(GtkWidget *button)
{
     gtk_widget_hide(button);
    gtk_widget_show(button);
}
/*############# Create a new codetree ( child of codeview )###########*/ 
void gsim_make_codeview_child( gchar *codeview_child_label )
{
	/*make the tab widget & menu lable for the child codetree */
	GtkWidget *codeview_tab;
	GtkWidget *codeview_menu_label;
	GtkWidget *codeview_tab_label;
	GtkWidget *codeview_tab_close;
	GtkWidget *codeview_scroll;
	
	/*popup menu entry for this codetree*/
	codeview_menu_label = gtk_label_new( codeview_child_label );
	
	/*construct the tab widget ( a label & close button) */
	codeview_tab = gtk_hbox_new( FALSE , 0);
	codeview_tab_label = gtk_label_new( codeview_child_label ) ;
	gtk_widget_set_name(codeview_tab_label,"tab");
	
	
	codeview_tab_close = gsim_small_close_button_new(-1,-1);

	g_signal_connect(codeview_tab_close,"clicked",G_CALLBACK(gsim_close_file),NULL);
#ifdef G_OS_WIN32  //tackle the widows gtk ui bug
    g_signal_connect(codeview_tab_close,"leave",G_CALLBACK(gsim_button_fix_win),codeview_tab_close);
#endif    	
	gtk_box_pack_start( GTK_BOX( codeview_tab ) , codeview_tab_label , TRUE , TRUE , 0);
	gtk_box_pack_start( GTK_BOX( codeview_tab ) , codeview_tab_close, FALSE , TRUE, 0);
	gtk_widget_show_all( codeview_tab );
	
	/*scrolled window for the codetree*/

	codeview_scroll = gtk_scrolled_window_new( NULL , NULL );
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(codeview_scroll),GTK_SHADOW_IN);
	gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( codeview_scroll ) ,
																GTK_POLICY_AUTOMATIC , GTK_POLICY_AUTOMATIC );
	
	/*make the tree to have code*/
	GtkWidget *codeview_tree;
	GtkTreeStore *codeview_store;
	GtkTreeModel *codeview_model;
	GtkTreeSelection *codeview_selector;
	
	codeview_store=gtk_tree_store_new(8,GDK_TYPE_PIXBUF,GDK_TYPE_PIXBUF,G_TYPE_STRING,G_TYPE_STRING,
	                                    G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING);
	codeview_tree=gtk_tree_view_new_with_model(GTK_TREE_MODEL(codeview_store));
	codeview_model=gtk_tree_view_get_model(GTK_TREE_VIEW(codeview_tree));
	codeview_selector=gtk_tree_view_get_selection(GTK_TREE_VIEW(codeview_tree));

	
	g_object_unref(G_OBJECT(codeview_store));
	
	/*------------make the columns and cells--------------------*/
	GtkTreeViewColumn *codeview_column;
	GtkCellRenderer *codeview_breakpoint,*codeview_tracker,*codeview_address,*codeview_label,
	                *codeview_mnemonic,*codeview_op1,*codeview_op2,*codeview_comment;
					
	codeview_column=gtk_tree_view_column_new();
	g_object_set(G_OBJECT(codeview_column),"title"," ADDRESS","resizable",FALSE,NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(codeview_tree),codeview_column);
	
	codeview_breakpoint=gtk_cell_renderer_pixbuf_new();
	g_object_set(G_OBJECT(codeview_breakpoint),"cell-background","NavyBlue",NULL);
	gtk_tree_view_column_pack_start(codeview_column,codeview_breakpoint,FALSE);
	gtk_tree_view_column_set_attributes(codeview_column,codeview_breakpoint,"pixbuf",BR_COL,NULL);
	
	codeview_tracker=gtk_cell_renderer_pixbuf_new();
	g_object_set(G_OBJECT(codeview_tracker),"cell-background","NavyBlue","xpad",0,NULL);
	gtk_tree_view_column_pack_start(codeview_column,codeview_tracker,FALSE);
	gtk_tree_view_column_set_attributes(codeview_column,codeview_tracker,"pixbuf",TR_COL,NULL);

	codeview_address=gtk_cell_renderer_text_new();
	g_object_set(G_OBJECT(codeview_address),"cell-background","NavyBlue","editable",TRUE,NULL);
	gtk_tree_view_column_pack_end(codeview_column,codeview_address,TRUE);
	gtk_tree_view_column_set_attributes(codeview_column,codeview_address,"text",ADDR_COL,NULL);
	g_signal_connect (codeview_address, "edited",G_CALLBACK (codeview_address_edited), NULL);
	
	codeview_label=gtk_cell_renderer_text_new();
	g_object_set(G_OBJECT(codeview_label),"cell-background","white","foreground","purple4","font","luxi sans italic","editable",TRUE,NULL);
	codeview_column=gtk_tree_view_column_new_with_attributes(" LABEL ",codeview_label,"text",LABEL_COL,NULL);
	g_signal_connect (codeview_label, "edited",G_CALLBACK (codeview_label_edited), NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(codeview_tree),codeview_column);
	
	codeview_mnemonic=gtk_cell_renderer_text_new();
	g_object_set(G_OBJECT(codeview_mnemonic),"foreground","NavyBlue","cell-background","WhiteSmoke","font","luxi sans bold",NULL);
	codeview_column=gtk_tree_view_column_new_with_attributes("MNEMONIC",codeview_mnemonic,"text",MNE_COL,NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(codeview_tree),codeview_column);
	
	codeview_op1=gtk_cell_renderer_text_new();
	g_object_set(G_OBJECT(codeview_op1),"foreground","blue","cell-background","snow",NULL);
	codeview_column=gtk_tree_view_column_new_with_attributes("  OP1  ",codeview_op1,"text",OP1_COL,NULL);
	g_signal_connect (codeview_op1, "edited",G_CALLBACK (codeview_op1_edited), NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(codeview_tree),codeview_column);
	
	codeview_op2=gtk_cell_renderer_text_new();
	g_object_set(G_OBJECT(codeview_op2),"foreground","blue","cell-background","snow",NULL);
	codeview_column=gtk_tree_view_column_new_with_attributes("  OP2  ",codeview_op2,"text",OP2_COL,NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(codeview_tree),codeview_column);
	
	codeview_comment=gtk_cell_renderer_text_new();
	g_object_set(G_OBJECT(codeview_comment),"foreground","RoyalBlue4","editable",TRUE,NULL);
	codeview_column=gtk_tree_view_column_new_with_attributes("COMMENT",codeview_comment,"text",COMMT_COL,NULL);
	g_signal_connect (codeview_comment, "edited",G_CALLBACK (codeview_comment_edited), NULL);
	gtk_tree_view_append_column(GTK_TREE_VIEW(codeview_tree),codeview_column);
	
	/*pack the tree in the scrollbar*/
	gtk_container_add(GTK_CONTAINER(codeview_scroll),codeview_tree);
	
	/*pack in the notebook*/
	gtk_notebook_prepend_page_menu( GTK_NOTEBOOK( codeview_notebook ) ,
									codeview_scroll , codeview_tab , codeview_menu_label );
	gtk_widget_show_all(codeview_notebook);
	
	/*Pop up menu when right clicked*/
	GtkWidget *codeview_popup;
	codeview_popup=gtk_menu_new();
	
	GtkWidget *enter_label;
	enter_label=gtk_menu_item_new_with_mnemonic(_("   Enter _Label"));
	gtk_menu_shell_append(GTK_MENU_SHELL(codeview_popup),enter_label);
	g_signal_connect(enter_label,"activate",G_CALLBACK(codeview_enter_label),NULL);
	
	GtkWidget *toggle_breakpoint;
	toggle_breakpoint=gtk_menu_item_new_with_mnemonic(_("   _Set / Remove Breakpoint       "));
	gtk_menu_shell_append(GTK_MENU_SHELL(codeview_popup),toggle_breakpoint);
	g_signal_connect(toggle_breakpoint,"activate",G_CALLBACK(gsim_toggle_breakpoint),NULL);
	
	GtkWidget *sep1;
	sep1=gtk_separator_menu_item_new();
	gtk_menu_shell_append(GTK_MENU_SHELL(codeview_popup),sep1);
	
	GtkWidget *insert_row_before;
	insert_row_before=gtk_menu_item_new_with_mnemonic(_("   Insert Row _Before"));
	gtk_menu_shell_append(GTK_MENU_SHELL(codeview_popup),insert_row_before);
	g_signal_connect(insert_row_before,"activate",G_CALLBACK(gsim_insert_row_before),NULL);
	
	GtkWidget *insert_row_after;
	insert_row_after=gtk_menu_item_new_with_mnemonic(_("   Insert Row _After"));
	gtk_menu_shell_append(GTK_MENU_SHELL(codeview_popup),insert_row_after);
	g_signal_connect(insert_row_after,"activate",G_CALLBACK(gsim_insert_row_after),NULL);
	
	GtkWidget *remove_row;
	remove_row=gtk_menu_item_new_with_mnemonic(_("   _Remove Row"));
	gtk_menu_shell_append(GTK_MENU_SHELL(codeview_popup),remove_row);
	g_signal_connect(remove_row,"activate",G_CALLBACK(gsim_remove_row),NULL);
	
	GtkWidget *sep2;
	sep2=gtk_separator_menu_item_new();
	gtk_menu_shell_append(GTK_MENU_SHELL(codeview_popup),sep2);
	
	GtkWidget *edit_;
	edit_=gtk_menu_item_new_with_mnemonic(_("   _Edit On/Off"));
	gtk_menu_shell_append(GTK_MENU_SHELL(codeview_popup),edit_);
	g_signal_connect(edit_,"activate",G_CALLBACK(gsim_edit),NULL);
	
	g_signal_connect_swapped(codeview_tree,"button-press-event",G_CALLBACK(codeview_pop_menu),codeview_popup);
	gtk_widget_show_all(codeview_popup);
	
	return;
}



/*############## Make the codeview ( a note book Widget )#############*/
GtkWidget *gsim_get_codview(void)
{
	codeview_notebook= gtk_notebook_new( );
	gtk_notebook_set_show_tabs(GTK_NOTEBOOK( codeview_notebook) ,TRUE);
	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(codeview_notebook),GTK_POS_BOTTOM);
	gtk_notebook_popup_enable(GTK_NOTEBOOK(codeview_notebook));
	gtk_notebook_set_scrollable(GTK_NOTEBOOK(codeview_notebook),TRUE);
    g_signal_connect(codeview_notebook,"switch-page",G_CALLBACK(gsim_page_switched),NULL);
	
	return codeview_notebook;
}
